在說明主幹開發的發布方式時,有提到從主幹或發布分支選定版本的做法。選定版本只是發布準備的一部分,團隊還需要準備成品、環境與部署步驟,並確認這個版本是否能正常部署與運作。
持續交付(Continuous Delivery,簡稱 CD)的目的,是讓變更能安全、快速地進入正式環境或交到使用者手上,並讓團隊能依需要安排發布。
一個版本能正常部署與運作,不代表後續版本也可以。程式會隨著開發改變,團隊也要跟著驗證新版本、處理發現的問題。持續交付所強調的「持續」,就是在日常開發中維持可以發布的狀態。
做好發布準備,不代表每次提交都要立即上線。如果版本通過事先安排的檢查與驗證後,就自動部署到正式環境,則稱為持續部署(Continuous Deployment)。
下圖以線上服務為例,說明程式變更後,各個步驟如何將結果回報給開發者。時間由上往下,呈現驗證與回饋的順序。

持續整合提供整合後的建置與測試結果;持續交付接著完成發布準備,透過部署與驗證,讓團隊知道還有哪些問題需要處理;持續部署則在通過必要檢查與驗證後,自動部署到正式環境。無論正式部署由人啟動或自動執行,都需要確認上線後的結果。
成品通過建置與測試,只能說明已經檢查的部分符合預期,還不能直接判斷是否可以發布。部署後的環境與服務互動,也需要確認。
團隊要先查看這個版本做過哪些測試。例如,前端與後端各自通過測試,還不代表兩者接在一起能正常運作。找出還沒確認的部分後,再安排部署後要做的測試。
延續 Nathan 團隊的情境。Elvina 與 Mandy 取得包含前後端程式、已通過建置與測試的成品後,先確認驗證紀錄是否包含前後端完整流程的測試,再確認哪些原有功能會受到影響,整理部署後要做的測試。
確認部署後要做的測試後,接著要準備成品和測試環境。正式部署要使用測試過的同一份成品。測試環境也要盡量接近正式環境,減少測試通過、上線後卻因環境不同而出錯的情況。
各環境不同的設定要和成品分開,在部署或執行時提供。測試與正式環境使用的軟體和依賴服務,則應盡量維持相同種類與版本。兩邊不必使用相同的主機規模、服務位址或資料。
以 Elvina 的前端為例,如果後端 API 網址在建置時就寫進程式檔案,換環境便需要重新建置。要沿用同一份成品,就需要讓程式在執行時讀取對應環境的設定。
Elvina、Mandy 可以與負責 SRE 的 Brent 一起確認設定的提供方式,並準備測試需要的前後端服務與資料。兩人整理出的前後端完整流程測試,就能在這個環境中執行。
有了成品與環境,就可以執行部署,接著確認程式是否正常啟動、是否能連接依賴服務,以及功能是否正常。如果等到決定發布才檢查,這些問題就會留到發布時才發現。
團隊可以把部署與檢查寫成腳本,接到持續整合的建置流程後面。建置通過後,就能將成品自動部署到測試環境,確認程式啟動與服務連接正常,再執行功能測試。測試與正式環境使用相同的部署方式,也能讓正式部署的步驟提早接受驗證。
必要的人工測試通過後,才能繼續交付。部署或測試失敗時,先處理問題,再重新驗證。如果改了程式,就要重新建置與驗證;如果只調整環境或設定,就重新執行受影響的部署與驗證步驟。
在 Nathan 團隊裡,Elvina、Mandy 與 Brent 一起把部署、確認程式啟動與服務連接的步驟寫進腳本。這些檢查通過後,再執行前面整理的功能測試。自動測試由流程執行,需要人工確認的部分則由 Elvina 與 Mandy 分工處理。
需求或依賴改變時,團隊也要調整測試、設定與腳本,讓後續版本仍能使用這套流程。在測試環境部署與驗證通過,不代表正式部署一定成功。因此,團隊也要在發布前準備好正式部署失敗時的處理方式。
正式部署失敗時,不一定能直接換回舊成品。部署過程中,設定、環境或資料可能已經改變,舊程式未必還能正常運作。因此,團隊要在發布前先想好還原方案,並確認方案是否可行,不能等到部署失敗才開始準備。
團隊需要在發布前先確認,如何判斷部署失敗、由誰處理,以及什麼情況下要停止後續發布。若打算透過恢復先前版本來處理,也要事先確認舊成品與設定、環境及資料是否相容,並驗證恢復步驟。
發生問題時,團隊再依原因決定修正後重新交付,或執行已確認可行的恢復步驟。無論採用哪種方式,都要確認服務是否恢復正常。
例如,如果這次部署調整了資料格式,新程式寫入的資料,舊程式不一定能讀取。換回舊成品不會自動還原資料,因此發布前就要確認:恢復舊程式時,現有資料是否還能使用,以及不相容的資料要如何處理。
持續交付是在日常開發中維持可以發布的狀態。團隊隨著程式變更完成必要驗證、準備部署與還原方案,就能依需要安排發布,不必等到要上線時才開始準備。
即使交付流程已經準備好,需要的程式若仍與其他未完成的功能綁在一起,團隊還是難以及早整合。接下來要處理的,就是如何拆分這些程式。